package com.imooc.service.impl;

import com.imooc.enums.OrderStatusEnum;
import com.imooc.enums.YesOrNo;
import com.imooc.mapper.OrderItemsMapper;
import com.imooc.mapper.OrderStatusMapper;
import com.imooc.mapper.OrdersMapper;
import com.imooc.pojo.*;
import com.imooc.pojo.bo.ShopcartBO;
import com.imooc.pojo.bo.SubmitOrderBO;
import com.imooc.pojo.vo.MerchantOrdersVO;
import com.imooc.pojo.vo.OrderVO;
import com.imooc.service.AddressService;
import com.imooc.service.ItemService;
import com.imooc.service.OrderService;
import com.imooc.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author Administrator
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private OrderItemsMapper itemsMapper;

    @Autowired
    private OrderStatusMapper orderStatusMapper;

    @Autowired
    private Sid sid;

    @Autowired
    private AddressService addressService;

    @Autowired
    private ItemService itemService;

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public OrderVO insertOrder(List<ShopcartBO> shopcartList, SubmitOrderBO submitOrderBO) {
        // 1. 接收前端传入子订单参数
        String addressId = submitOrderBO.getAddressId();
        String itemSpecIds = submitOrderBO.getItemSpecIds();
        String userId = submitOrderBO.getUserId();
        Integer payMethod = submitOrderBO.getPayMethod();
        String leftMsg = submitOrderBO.getLeftMsg();

        String orderId = sid.nextShort();

        // 邮费默认为零
        Integer postAmount = 0;

        // 2.1 根据用户userId和addressId获取用户地址数据
        UserAddress userAddress = addressService.getByByUserIdAndAddressId(userId, addressId);

        Orders orders = new Orders();

        // 保存用户地址到订单表中
        orders.setReceiverName(userAddress.getReceiver());
        orders.setReceiverMobile(userAddress.getMobile());
        orders.setReceiverAddress(userAddress.getProvince() + " "
                + userAddress.getCity() + " "
                + userAddress.getDistrict() + " "
                + userAddress.getDetail());
        orders.setId(orderId);
        orders.setLeftMsg(leftMsg);
        orders.setUserId(userId);
        orders.setPostAmount(postAmount);
        orders.setPayMethod(payMethod);
        orders.setIsComment(YesOrNo.NO.type);
        orders.setIsDelete(YesOrNo.NO.type);
        orders.setCreatedTime(new Date());
        orders.setUpdatedTime(new Date());

        // 默认订单价格
        Integer totalAmount = 0;
        Integer realPayAmount = 0;

        // 2. 创建子订单参数
        String[] specIds = StringUtils.split(itemSpecIds);

        List<ShopcartBO> toBeRemovedShopcatdList = new ArrayList<>();

        for (String specId : specIds) {
            // TODO 整合redis后，商品购买的数量重新从redis的购物车中获取
            ShopcartBO bo = getByCount(shopcartList, specId);
            Integer buyCounts = bo.getBuyCounts();
            ItemsSpec itemsSpec = itemService.getItemsSpecsBySpecId(specId);
            // 获取优惠价和原价数据
            totalAmount += itemsSpec.getPriceNormal() * buyCounts;
            realPayAmount += itemsSpec.getPriceDiscount() * buyCounts;

            // 2.2 根据商品id，获得商品信息以及商品图片
            String itemId = itemsSpec.getItemId();
            Items item = itemService.getById(itemId);
            String imgUrl = itemService.queryItemMainImgById(itemId);

            // 2.3 填充订单状态数据
            OrderItems orderItems = new OrderItems();
            orderItems.setBuyCounts(buyCounts);
            orderItems.setId(sid.nextShort());
            orderItems.setItemId(itemId);
            orderItems.setItemName(item.getItemName());
            orderItems.setItemImg(imgUrl);
            orderItems.setItemSpecId(specId);
            orderItems.setItemSpecName(itemsSpec.getName());
            orderItems.setBuyCounts(buyCounts);
            orderItems.setPrice(itemsSpec.getPriceDiscount());
            orderItems.setOrderId(orderId);
            itemsMapper.insertSelective(orderItems);
            // 2.4 扣除库存
            itemService.decreaseItemSpecStock(specId, buyCounts);

        }
        // 3. 填充主订单数据
        orders.setRealPayAmount(realPayAmount);
        orders.setTotalAmount(totalAmount);
        ordersMapper.insertSelective(orders);

        // 4. 填充订单状态数据(等待支付)
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setCreatedTime(new Date());
        orderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
        orderStatusMapper.insertSelective(orderStatus);


        // 5. 构建商户订单，用于传给支付中心
        MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
        merchantOrdersVO.setMerchantOrderId(orderId);
        merchantOrdersVO.setMerchantUserId(userId);
        merchantOrdersVO.setAmount(realPayAmount + postAmount);
        merchantOrdersVO.setPayMethod(payMethod);

        // 6. 构建自定义订单vo
        OrderVO orderVO = new OrderVO();
        orderVO.setOrderId(orderId);
        orderVO.setMerchantOrdersVO(merchantOrdersVO);
        orderVO.setToBeRemovedShopcatdList(toBeRemovedShopcatdList);
        return orderVO;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public Integer updateState(String marchNo, Integer orderState) {
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(marchNo);
        orderStatus.setOrderStatus(orderState);
        orderStatus.setPayTime(new Date());
        return orderStatusMapper.updateByPrimaryKeySelective(orderStatus);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    @Override
    public OrderStatus queryOrderState(String orderId) {
        return orderStatusMapper.selectByPrimaryKey(orderId);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void closeOrder() {
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
        List<OrderStatus> orderStatuses = this.orderStatusMapper.select(orderStatus);
        orderStatuses.forEach(new Consumer<OrderStatus>() {
            @Override
            public void accept(OrderStatus orderStatus) {
                Date createdTime = orderStatus.getCreatedTime();
                int days = DateUtil.daysBetween(createdTime, new Date());
                if (days >= 1) {
                    this.close(orderStatus.getOrderId());
                }
            }

            // 更新订单状态(时间一到更新所有待支付的状态)
            private void close(String orderId) {
                OrderStatus os = new OrderStatus();
                os.setOrderStatus(OrderStatusEnum.CLOSE.type);
                os.setOrderId(orderId);
                os.setCloseTime(new Date());
                orderStatusMapper.updateByPrimaryKeySelective(os);
            }
        });
    }

    //***************************************************** 私有方法 ***********************************************//

    /**
     * 获取购物车数量
     */
    private ShopcartBO getByCount(List<ShopcartBO> shopcartList, String specId) {
        for (ShopcartBO cart : shopcartList) {
            if (cart.getSpecId().equals(specId)) {
                return cart;
            }
        }
        return null;
    }

}
